package com.dm.action;

import com.dm.common.Const;
import com.dm.dto.FileAttributeDto;
import com.dm.dto.FilesDto;
import com.dm.dto.ResponseDto;
import com.dm.dto.input.FileDto;
import com.dm.dto.input.FileSearchDto;
import com.dm.dto.input.UserDto;
import com.dm.service.FileService;
import com.dm.utils.FileUtil;
import com.dm.utils.JsonDateValueProcessor;
import com.dm.utils.JsonRequestDataUtil;
import com.opensymphony.xwork2.ActionSupport;
import lombok.Data;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * @author hqw521@qq.com
 * @date 2018/11/17 12:40
 */
@Data
@Namespace("/dm/file")
@ParentPackage("json-default")
@Results({@Result(name = "jsonData", type = "json", params = {"root", "jsonData"})})
public class FileAction extends ActionSupport {
    private String jsonData;

    /**
     * 提交过来的文件
     */
    private File file;

    /**
     * 提交过来的文件名
     */
    private String fileFileName;
    /**
     * 文件类型
     */
    private String fileContentType;

    private InputStream attachstream;

    private String attachname;

    private String ids;

    private Integer folderId;

    private String folderPath;

    public String getAttachname() {
        // 对不同浏览器传过来的文件名进行编码
        try {
            return encodeDownloadFilename(attachname, ServletActionContext.getRequest().getHeader("User-Agent"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return attachname;
    }

    @Autowired
    private FileService fileService;

    @Action("createFile")
    public String createFile() {
        FileDto fileDto = (FileDto) JsonRequestDataUtil.getBean(ServletActionContext.getRequest(), FileDto.class);
        ResponseDto responseDto = fileService.createFile(fileDto);
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("uploadFile")
    public String uploadFile() {
        System.out.println(this.getFileFileName() + "\n" + this.getFileContentType() + "\n" + this.getFolderPath());
        ResponseDto responseDto = fileService.uploadFile(this.getFile(), this.getFileFileName(), this.getFileContentType(), this.getFolderPath());
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("addFile")
    public String addFile() {
        FileDto fileDto = (FileDto) JsonRequestDataUtil.getBean(ServletActionContext.getRequest(), FileDto.class);
        ResponseDto responseDto = fileService.addFile(fileDto);
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("findFiles")
    public String findFiles() {
        UserDto userDto = (UserDto) JsonRequestDataUtil.getBean(ServletActionContext.getRequest(), UserDto.class);
        ResponseDto<List> responseDto = fileService.findFiles(userDto);
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("findFilesByFolderId")
    public String findFilesByFolderId() {
        FileDto fileDto = (FileDto) JsonRequestDataUtil.getBean(ServletActionContext.getRequest(), FileDto.class);
        ResponseDto<List> responseDto = fileService.findFilesByFolder(fileDto.getUserId(), fileDto.getFolderId());
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("fileRename")
    public String fileRename() {
        FileDto fileDto = (FileDto) JsonRequestDataUtil.getBean(ServletActionContext.getRequest(), FileDto.class);
        ResponseDto responseDto = fileService.fileRename(fileDto);
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("deleteFiles")
    public String deleteFiles() {
        JSONObject jsonObject = JsonRequestDataUtil.getJsonRequestData(ServletActionContext.getRequest());
        // 文件路径
        String pathStr = (String) jsonObject.get("fileRelativePaths");
        String[] fileRelativePaths = pathStr.split(",");
        // 文件ID
        String idStr = (String) jsonObject.get("ids");
        String[] ids = idStr.split(",");
        // 用户ID
        Integer userId = (Integer) jsonObject.get("userId");
        ResponseDto responseDto = fileService.deleteFiles(userId, ids, fileRelativePaths);
        jsonData = JSONObject.fromObject(responseDto).toString();
        return Const.JSON;
    }

    @Action("findFileAttribute")
    public String findFileAttribute() {
        JSONObject jsonObject = JsonRequestDataUtil.getJsonRequestData(ServletActionContext.getRequest());
        Integer fileId = (Integer) jsonObject.get("fileId");
        ResponseDto<FileAttributeDto> responseDto = fileService.findFileAttribute(fileId);
        JsonConfig jsonConfig = new JsonConfig();
        // 将自定已的date转换器注册进去
        jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
        jsonData = JSONObject.fromObject(responseDto, jsonConfig).toString();
        return Const.JSON;
    }

    /**
     * 单文件下载
     *
     * @return
     */
    @Action(value = "downloadFile",
            results = {@Result(name = "download", type = "stream",
                    params = {
                            "contentType", "application/octet-stream",
                            "inputName", "attachstream",
                            "contentDisposition", "attachment;filename=\"${attachname}\"",
                            "bufferSize", "4096"
                    })})
    public String downloadFile() {
        String relativePath = this.getIds();
        try {
            attachstream = FileUtil.download(Const.uploadHost + relativePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Const.DOWNLOAD;
    }

    /**
     * 多文件下载
     *
     * @return
     */
    @Action(value = "downloadMultiFile",
            results = {@Result(name = "downloadMulti", type = "stream",
                    params = {
                            "contentType", "application/octet-stream",
                            "inputName", "attachstream",
                            "contentDisposition", "attachment;filename=\"${attachname}\"",
                            "bufferSize", "4096"
                    })})
    public String downloadMultiFile() {
        System.out.println(this.getIds());
        String[] ids = this.getIds().split(",");
        attachstream = fileService.downloadMultiFile(ids);
        attachname = "文档_" + FileUtil.generateName() + ".zip";
        return "downloadMulti";
    }

    @Action("fileSearch")
    public String fileSearch() {
        FileSearchDto fileSearchDto = (FileSearchDto) JsonRequestDataUtil.getBean(ServletActionContext.getRequest(), FileSearchDto.class);
        ResponseDto<List<FilesDto>> responseDto = fileService.fileSearch(fileSearchDto);
        JsonConfig jsonConfig = new JsonConfig();
        // 将自定已的date转换器注册进去
        jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());
        jsonData = JSONObject.fromObject(responseDto, jsonConfig).toString();
        return Const.JSON;
    }

    @Action("updateClickNum")
    public void updateClickNum() {
        JSONObject jsonObject = JsonRequestDataUtil.getJsonRequestData(ServletActionContext.getRequest());
        Integer fileId = (Integer) jsonObject.get("fileId");
        fileService.updateClickNum(fileId);
    }

    private String encodeDownloadFilename(String name, String agent) throws IOException {
        String browser = "Firefox";
        if (agent != null && agent.contains(browser)) {
            name = "=?UTF-8?B" + new BASE64Encoder().encode(name.getBytes("utf-8")) + "?=";
        } else if (name != null) {
            name = URLEncoder.encode(name, "utf-8");
        }
        return name;
    }
}

